package bancosys.tec.services.junitx;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.Arrays;
import java.util.List;

import bancosys.tec.services.IntegrationTestCase;

/**
 * Define que um TestRunner pode ter mais de um arquivo selecionado para execução.
 * 
 * @author finx
 * @created May 3, 2012
 */
public class MultiTestRunnerTestSuite extends IntegrationTestSuite {

    /**
     * Construtor.
     * 
     * @param <T> tipo da classe a ser instanciada.
     * @param clazz classe a ser instanciada.
     * @param baseTestLocation path dos testes.
     */
    public <T extends IntegrationTestCase> MultiTestRunnerTestSuite(Class<T> clazz, String baseTestLocation) {
        super();

        Constructor<T> constructor;
        Constructor<T> constructorURL;
        T testCase;

        if (!IntegrationTestCase.class.isAssignableFrom(clazz)) {
            this.addTest(warning("Class " + clazz.getName() + " does not extend the superclass IntegrationTestCase"));
            return;
        }

        try {
            constructor = clazz.getConstructor(new Class[]{ List.class });
            constructorURL = clazz.getConstructor(new Class[]{ URL.class });
        } catch (NoSuchMethodException e) {
            this.addTest(warning("Class " + clazz.getName() + " has no public constructor TestCase(URL) or TestCase(String)"));
            return;
        }

        if (!Modifier.isPublic(clazz.getModifiers())) {
            this.addTest(warning("Class " + clazz.getName() + " is not public"));
            return;
        }

        try {
            String[] tests = baseTestLocation.split(",");
            testCase = constructor.newInstance(new Object[]{ Arrays.asList(tests) });
            this.createTestCases(constructorURL, testCase);
        } catch (Exception e) {
            e.printStackTrace();
            this.addTest(warning("Could not create new instance of " + clazz.getName() + ", " + e.getMessage()));
            return;
        }

        if (this.testCount() == 0) {
            this.addTest(warning("No tests found in " + clazz.getName()));
        }
    }
}
